package com.ttbj.rule.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ttbj.move_rule.po.BillDistance;
import com.ttbj.product.bean.dto.CargoDto;
import com.ttbj.rule.po.BillDis;
import com.ttbj.rule.po.CarriageRule;
import com.ttbj.rule.service.BillStrategy;
import com.ttbj.rule.service.context.BillContext;
import com.ttbj.util.Assert;

/**
 * Final formal 阶梯式按里程计费
 * 
 * @author Administrator
 *
 */
public class BillDistanceStrategy implements BillStrategy {

	public static Logger logger = LoggerFactory.getLogger(BillDistanceStrategy.class);

	@Override
	public Float strategyInterface(Float distance, CargoDto cargo, CarriageRule bill) throws Exception {
		Assert.assertNonNullField(bill, "参数缺失获取计费规则失败", "wtTiming", "wtCarType", "billDistance");
		Float fee = getFee(distance, bill.getBillDistance());// 未加权重费用
		logger.info("纯费用:{}", fee);
		fee = null == fee ? 0f : fee;
		// 加入车辆类型权重
		Float wtCarType = bill.getWtCarType();
		logger.info("汽车类型权重:{}", wtCarType);
		// 加入昼夜权重
		Float wtTiming = bill.getWtTiming();
		logger.info("昼夜权重:{}", wtTiming);
		return fee * wtCarType * wtTiming;
	}

	private Float getOne(Float disance, BillDis distanceRule) { // 起步价
		Float distanceStartPrice = distanceRule.getDistanceStartPrice();
		logger.info("总里程数:{}公里",disance);
		logger.info("起步费用:{}", distanceStartPrice);
		return distanceStartPrice;
	}

	private Float getTwo(Float disance, BillDis distanceRule) { // 超出起步价
		Float one = getOne(disance, distanceRule);
		Float subKile = disance - distanceRule.getDistanceStartMileage();
		logger.info("扣除起步剩余里程:{}公里", subKile);
		if(subKile > distanceRule.getDistanceLong()){
			subKile = distanceRule.getDistanceLong();
			logger.info("超出长途起步里程");
		}
		Float price = one + subKile * distanceRule.getDistanceBeyondPrice();
		logger.info("超出起步和起步的总费用:{}元", price);
		return price;
	}

	private Float getThree(Float disance, BillDis distanceRule) { // 超出长途价
		Float two = getTwo(disance, distanceRule);
		Float subKile = disance - distanceRule.getDistanceLong();
		Float price =  two + subKile * distanceRule.getDistanceLongPrice();
		logger.info("剩余长途里程:{}公里", subKile);
		logger.info("长途费用:{}元", price);
		return price;
	}

	private Float getFee(Float disance, BillDis distanceRule) {
		Float fee = null;
		// 隶属于哪种距离起步还是长途
		Integer billFlag = disance > distanceRule.getDistanceLong() ? 3 : (disance > distanceRule.getDistanceStartMileage() ? 2 : 1);
		switch (billFlag) {
		case 1:
			fee = getOne(disance, distanceRule);
			break;
		case 2:
			fee = getTwo(disance, distanceRule);
			break;
		case 3:
			fee = getThree(disance, distanceRule);
			break;
		default:
			fee = 0f;
			break;
		}
		return fee;
	}

}
